﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AtomicTypes;
using QLabValues;

namespace NumericalCalculations
{
    public partial class Functions
    {
        private Dictionary<string, string> topics = null;
        public List<IQLabValue> help(List<IQLabValue> o)
        {
            if (topics == null)
            {
                topics = new Dictionary<string, string>();
                InitializeHelpTopics();
            }

            if (o.Count == 1)
            {
                var argument = o.ElementAt(0);
                var argType = argument.GetEnumType();
                if (argType == IQLabValueType.QCharNDimArray)
                {
                    var chars = new QCharNDimArray(argument);
                    if (Helper.IsString(chars))
                    {
                        var option = Helper.QCharNDimArrayToStringList(chars).ElementAt(0);
                        string helptext;
                        if (topics.TryGetValue(option, out helptext))
                            return new IQLabValue[] {new QCharNDimArray(helptext)}.ToList();
                        else
                            throw (new NumericalCalculationsException(String.Format("{0} not found", option)));
                    }
                }
            }
            else if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> help \n Help only supports one topic"));

            var s = new StringBuilder("Supported topics:\r\n");
            foreach (var topic in topics)
            {
                s.AppendLine(topic.Key);
            }

            return new IQLabValue[] {new QCharNDimArray(s.ToString())}.ToList();
        }

        private void InitializeHelpTopics()
        {
            topics = new Dictionary<string, string>();

            topics.Add("help", 
@"    Display help text in Command Window.

      help, by itself, lists all help topics.
 
      help FUN displays a description of and syntax for the function FUN.
 
      T = help(TOPIC) returns the help text for TOPIC as a string, with
      each line separated by \n. TOPIC is any allowable argument for help.
 
      EXAMPLES:
      help plot - displays help for the PLOT function.
      t = help('plot') - gets help for the function PLOT and stores it as
      a string in t.
");

            topics.Add("axis", 
@" axis  Control axis scaling and appearance.
    axis([XMIN XMAX YMIN YMAX]) sets scaling for the x- and y-axes
       on the current plot.
    axis([XMIN XMAX YMIN YMAX ZMIN ZMAX]) sets the scaling for the
       x-, y- and z-axes on the current 3-D plot.
    axis([XMIN XMAX YMIN YMAX ZMIN ZMAX CMIN CMAX]) sets the
       scaling for the x-, y-, z-axes and color scaling limits on
       the current axis (see CAXIS). 
    V = axis returns a row vector containing the scaling for the
       current plot.  If the current view is 2-D, V has four
       components; if it is 3-D, V has six components.
 
    axis AUTO  returns the axis scaling to its default, automatic
       mode where, for each dimension, 'nice' limits are chosen based
       on the extents of all line, surface, patch, and image children.
    axis MANUAL  freezes the scaling at the current limits, so that if
       HOLD is turned on, subsequent plots will use the same limits.
    axis TIGHT  sets the axis limits to the range of the data.
");
            topics.Add("grid",
@" grid   Grid lines.
    grid ON adds major grid lines to the current axes.
    grid OFF removes major and minor grid lines from the current axes. 
    grid MINOR toggles the minor grid lines of the current axes.
    grid, by itself, toggles the major grid lines of the current axes.
");
            topics.Add("plot", 
@" plot   Linear plot. 
    
    plot(X,Y) plots vector Y versus vector X.
 
    plot(Y) plots the columns of Y versus their index.
    If Y is complex, plot(Y) is equivalent to plot(real(Y),imag(Y)).
    In all other uses of plot, the imaginary part is ignored.
 
    Various line types, plot symbols and colors may be obtained with
    plot(X,Y,S) where S is a character string made from one element
    from any or all the following 3 columns:
 
           b     blue          .     point            
           g     green         o     circle           
           r     red           x     x-mark           
           c     cyan          +     plus             
           m     magenta       *     star             
           y     yellow        s     square
           k     black         d     diamond
           w     white         v     triangle (down)
                               ^     triangle
                               <     triangle
                               >     triangle
                               p     pentagram
                               h     hexagram
    
    For example, plot(X,Y,'c+') plots a cyan line with a plus at each 
    data point.
 
    plot(X1,Y1,S1,X2,Y2,S2,X3,Y3,S3,...) combines the plots defined by
    the (X,Y,S) triples, where the X's and Y's are vectors and the S's
    are strings.  
 
    For example, plot(X,Y,'yd',X,Y,'go') plots the data twice, with a
    yellow line with diamonds and green line with circles at the data
    points.
 
    The plot command, if no color is specified, makes automatic use of
    the colors specified by the axes ColorOrder property.
 
    If you do not specify a marker type, plot uses no marker. 
 
");
            topics.Add("hold", 
@" hold   Hold current graph
    hold ON holds the current plot and all axis properties so that
    subsequent graphing commands add to the existing graph.
    hold OFF returns to the default mode whereby PLOT commands erase 
    the previous plots and reset all axis properties before drawing 
    new plots.
    hold, by itself, toggles the hold state.
    hold does not affect axis autoranging properties.
");
            topics.Add("figure",
@" figure Create figure window.
    figure, by itself, creates a new figure window, and returns
    its handle.
  
    figure(H) makes H the current figure, forces it to become visible,
    and raises it above all other figures on the screen.  If Figure H
    does not exist, and H is an integer, a new figure is created with
    handle H.
");
            topics.Add("clf",
@" clf Clear current figure.
    clf deletes all lines and bars from the current figure.
 
    clf RESET deletes all lines and bars from the current figure and
    raises it above all other figures on the screen.
 
    clf(FIG) or clf(FIG,'RESET') clears the single figure with handle FIG.
");
            topics.Add("legend",

@" legend Display legend.
    legend(string1,string2,string3, ...) puts a legend on the current plot
    using the specified strings as labels. legend works on line graphs only.
 
    legend OFF removes the legend from the current axes.
 
    legend TOGGLE toggles legend on or off.  If no legend exists for the
    current axes one is created using default strings. The default
    string for an object is a string of the form 'data1','data2', etc.
 
    legend HIDE makes legend invisible.
    legend SHOW makes legend visible. If no legend exists for the
    current axes one is created using default strings.
 
    legend BOXOFF  makes legend background box invisible when legend is
    visible.
    legend BOXON makes legend background box visible when legend is visible.
");
            topics.Add("xlabel", 
@" xlabel X-axis label.
    xlabel('text') adds text beside the X-axis on the current axis.
");
            topics.Add("ylabel",
@" ylabel Y-axis label.
    ylabel('text') adds text beside the Y-axis on the current axis.
");
            topics.Add("title", 
@" title Graph title.
    title('text') adds text at the top of the current axis.");
            
            topics.Add("bar",
@" bar Bar graph.
    bar(X,Y) draws the columns of the M-by-N matrix Y as M groups of N
    vertical bars.  The vector X must not have duplicate values.
 
    bar(Y) uses the default value of X=1:M.  For vector inputs, bar(X,Y)
    or bar(Y) draws LENGTH(Y) bars.  The colors are set by the ColorOrder.
 
    bar(...,LINESPEC) uses the line color specified (one of 'rgbymckw').
 ");
        }
    }
}

